#!/usr/bin/env python
import os,sys,time

# add self to search path for testing
if __name__ == '__main__':
    sys.path.append("../python_modules")

import general_util
from wrap_text import wrap_text

class custom_log (object):
    
    def __init__ (self, module, error_file_name = '', quiet = False):
        """
        __init__

            only use pipeline.log of genome project if no log filename specified
            
                if no genome project use stderr:

        """
        self.module=module
        self.new_line_on_exit=1
        self.quiet = quiet
        self.log_to_file = True
        if error_file_name =='':
            try:
                import get_parameter_path
                error_file_name = os.path.join(get_parameter_path.project_path, 'pipeline.log')
                self.error_file = open(error_file_name, 'a')
            except ImportError:
                self.error_file = sys.stderr
                self.log_to_file = False
        else:
            try:
                self.error_file = open(error_file_name, 'a')
            except IOError, e:
                self.error_file = sys.stderr
                self.error_to_log("Failed to open log file" + str(e))
                self.log_to_file = False
                

        
    def no_new_line_on_exit (self):
        """
        no_new_line_on_exit

            do not print new line when exiting module

        """
        self.new_line_on_exit = 0

    def pass_through (self, message):
        """
        pass_through

            print without preamble

        """
        if self.log_to_file:
            self.error_file.write(wrap_text(message, 
                                            '',
                                            '',                 # indent               
                                            150) + "\n")            # wrap at 150          
        if not self.quiet:
            print >>sys.stderr, wrap_text(message, "", "", 120)

    def preamble_for_log (self, module_width):
        """
        preamble_for_log

            returns time stamp & module which prefixes every entry in the log
        """
        if time:
            return (time.strftime("%d/%m/%Y (%H:%M:%S)") + 
                        (" %-" + str(module_width) + "s ") % self.module)
        else:
            return ((" " * 22 + " %-" + str(module_width) + "s ") % self.module)
        
        
    def info (self, message):
        """
        infof

            print informative message to log and STDERR
        """
        self.info_to_log(message)
        self.debug(message)
        
    def info_to_log (self, message):
        """
        info_to_log

            helper function for info
            prints message to log
        """
        if not self.log_to_file:
            return
            
        preamble = self.preamble_for_log(30)
        self.error_file.write(wrap_text(message, 
                                        preamble,    # preamble on each line
                                        '    ',                 # indent               
                                        150) + "\n")            # wrap at 150          
        self.error_file.flush()

    def info_unwrapped_to_log (self, message):
        """
        info_unwrapped_to_log

            helper function for info
            prints message to log without wrapping
        """
        if not self.log_to_file:
            return
        preamble = self.preamble_for_log(30)
        self.error_file.write(wrap_text(message, 
                                        preamble,    # preamble on each line
                                        '    ',                 # indent               
                                        10000) + "\n")          # practically unwrapped
        self.error_file.flush()

    def info_unwrapped (self, message):
        """
        infof

            print informative message to log and STDERR
        """
        self.info_unwrapped_to_log(message)
        self.debug_unwrapped(message)
        
    def debug (self, message):
        """
            only print to STDERR
        """
        if self.quiet:
            return
        print >>sys.stderr, wrap_text(message, "        ", "  ", 120)

        
    def debug_unwrapped (self, message):
        """
            only print to STDERR
        """
        if self.quiet:
            return
        print >>sys.stderr, "        " + message


    def warning_to_log (self, message):
        """
        warning_to_log

            helper function for warning and warningf
            prints message to log
        """
        if not self.log_to_file:
            return
        preamble = self.preamble_for_log(34)
        self.error_file.write(wrap_text(message, 
                                        preamble + "WARN: ",    # preamble on each line
                                        '    ',                 # indent
                                        150) + "\n")            # wrap at 150
        self.error_file.flush()

    def warning (self, message):
        """
        warning

            prints warning message to log and stderr
        """
        self.warning_to_log(message)
        general_util.print_warning(message)


    def error_to_log (self, message):
        """
        error_to_log

            helper function for error
            prints message to log
        """
        if not self.log_to_file:
            return
        preamble = self.preamble_for_log(34)
        self.error_file.write(wrap_text(message, 
                                        preamble + "ERROR: ",    # preamble on each line
                                        '    ',                 # indent
                                        150) + "\n")            # wrap at 150
        self.error_file.flush()
        
    def die_error (self, message):
        """
        error

            prints error message to log and stderr
        """
        self.error_to_log(message)
        general_util.die_error(message)


    def __del__ (self):
        """
        __del__

            print new line after log
            
        """
        if self.new_line_on_exit:
            self.info('')
            
    def info_unindented_lines (self, lines, further_indent = ""):
        """
        helper function for writting out contents of file to log
        """
        import re
        regex_indent =  re.compile("^( *)")
        if not len(lines):
            return
        min_indent = min (len(regex_indent.search(x).group(0)) for x in lines)
        for line in lines:
            self.info(further_indent + line[min_indent:].rstrip("\n"))


        
def unit_test():
    log = custom_log(__name__, "test.log")
    log.debug("Some message")
    log.info("Some long informationary messag which spans lines and lines. And goes "
             "on for ever and ever. Can you just take this?"
             "Some long informationary messag which spans lines and lines. And goes "
             "on for ever and ever. Can you just take this?")
    log.warning("Some long informationary messag which spans lines and lines. And goes "
             "on for ever and ever. Can you just take this?"
             "Some long informationary messag which spans lines and lines. And goes "
             "on for ever and ever. Can you just take this?")
    log.error("Some long informationary messag which spans lines and lines. And goes "
             "on for ever and ever. Can you just take this?"
             "Some long informationary messag which spans lines and lines. And goes "
             "on for ever and ever. Can you just take this?")
    print "Done"

if __name__ == '__main__':
    unit_test()
    unit_test()    
